#ifndef REGIONGROWING_H
#define REGIONGROWING_H

#include "SegmentationTechnique.h"
#include <QDebug>
#include <QMultiMap>

#include "Transformations.h"
#include <math.h>

/**
  * This class represents the segmentation technique RegionGrowing
  */
class RegionGrowing : public SegmentationTechnique
{

    QMultiMap<float, int> * nonVisitedPixels;

    bool autoTolerance;
    float tol;
    float prop;

private:
    
    /**
      * It returns the pixels intensities Average.
      */
    static float getAvg(QImage * img, QList<int> * pixels);

    /**
      * It returns the pixels intensities Standard Desviation.
      */
    static float getStandardDeviation(QImage * img, QList<int> * pixels);

    /**
      * This method checks if the pixel is or is not accepted by the acceptance criterion. This criterion checks if
      * the average of the differences between each neighboring pixel and the given intensity is less than the established criterion.
      *
      * @param pixel Pixel to evaluate.
      * @param tolerance Maximimum difference allowed to consider a neighbor similar to the central pixel.
      * @param avgIntensity Average intensity of the seed in the region.
      * @param proportion Minimum proportion of neighboring pixels which intensity difference with the avgIntensity have to
      *        be less than the tolerance in order to include it into the region.
      * @return Returns a bool value which indicates if the pixel is or not included into the region.
      */
    bool accepted( int pixel, float tolerance, float avgIntensity, float proportion);

    /**
      * It calculates the Tolerance of the region, considering it as the average of the deviation among the neighbors of all seeds.
      * @param pixels This map contains the pixels from which we want to calculate the tolerance (the pixel number is in the "value" field of the map, not in the key.
      * @returns Returns the tolerance value for the seed in the map.
      */
    float calculateTolerance(QMultiMap<float, int> * seeds);

    /**
      * This method calculates the quality factor of the pixel in the image.
      *
      * @param pixel Pixel to calculate the quality factors.
      * @return Returns a quality factor which indicates how similar is the pixel to the region.
      */
    float getQualityFactor( int pixel, float avgIntensity );

public:
    RegionGrowing();

    /**
      * Set the initial coordinates for the RegionGrowing algortihm
      *
      * @param x, y Coordinates of the seed point.
      */
    void addSeedPoint( int xI, int yI );

    /**
      * Apply the segmentation algorithm to the image
      *
      * @param image Image to segment.
      * @return Returns the segmented image.
      */
    Segmentation * segment();

    void setAutoTolerance(bool autoTol) { autoTolerance = autoTol; }

    void setTolerance(float initTol) { tol = initTol; }

    void setProportion(float p) { prop = p; }
};

#endif // REGIONGROWING_H
